Ext.namespace("org.microsite.util");

org.microsite.util.BrowserTree = Ext.extend(Ext.tree.TreePanel, {
    useArrows : true,
    autoScroll : true,
    animate : true,
    enableDD : false,
    containerScroll : true,
    rootVisible : true,
    
    root : null,
    
    nodeCreators : {
        'Host' : function(parent, data) {
            return new Ext.tree.AsyncTreeNode({
                data : data,
                text : data.name + ' (' + data.ip + ')',
                draggable : false,
                iconCls : 'hosticon',
                
                service : [ServerRemote.sublist],
                createServiceParam : function(node) {return [node.attributes.data.id]}
            });
        },
        'Server' : function(parent, data) {
            return new Ext.tree.AsyncTreeNode({
                data : data,
                text : data.name + ' (' + data.type + ')',
                draggable : false,
                iconCls : {
                    'WWW' : 'wwwicon',
                    'J2EE' : 'servericon',
                    'DBMS' : 'dbmsicon',
                    'SVN' : 'svnicon',
                    'SMTP' : 'mailicon',
                    'POP3' : 'mailicon',
                    'IMAP' : 'mailicon',
                    'FTP' : 'ftpicon',
                    'Samba' : 'smbicon',
                    'NFS' : 'smbicon',
                    'SSH' : 'smbicon'
                }[data.type],
                
                service : [DatabaseRemote.sublist, DeploymentRemote.sublist, ShareRemote.sublist, FileSetRemote.sublist],
                createServiceParam : function(node) {return [node.attributes.data.id]}
            });
        },
        'Database' : function(parent, data) {
            return new Ext.tree.TreeNode({
                data : data,
                text : data.name,
                draggable : false,
                iconCls : 'dbicon'
            });
        },
        'Deployment' : function(parent, data) {
            return new Ext.tree.TreeNode({
                data : data,
                text : data.name + ' (' + data.code + ')',
                draggable : false,
                iconCls : 'deploymenticon',
                
                service : [ProjectRemote.sublist],
                createServiceParam : function(node) {return [node.attributes.data.id]}
            });
        },
        'Project' : function(parent, data) {
            return new Ext.tree.TreeNode({
                data : data,
                text : data.name,
                draggable : false,
                iconCls : 'projecticon',
                
                service : [FileSetRemote.sublistInProject],
                createServiceParam : function(node) {return [node.attributes.data.id]}
            });
        },
        'Share' : function(parent, data) {
            return new Ext.tree.TreeNode({
                data : data,
                text : data.name,
                draggable : false,
                iconCls : 'shareicon'
            });
        },
        'FileSet' : function(parent, data) {
            return new Ext.tree.TreeNode({
                data : data,
                text : data.name,
                draggable : false,
                iconCls : 'fileseticon'
            });
        },
        'Group' : function(parent, data) {
            return new Ext.tree.AsyncTreeNode({
                data : data,
                text : data.name,
                draggable : false,
                
                service : [GroupRemote.sublist, HostRemote.sublist, ProjectRemote.sublistInGroup],
                createServiceParam : function(node) {return [node.attributes.data.id]}
            });
        }
    },
    
    createNode : function(parent, data) {
        return this.nodeCreators[data.getType()].call(this, parent, data);
    },
    
    initComponent : function() {
        if (this.root) this.root = this.createNode(null, this.root);
        this.loader = new Emp2.tree.DWRTreeMultiLoader({
            nodeCreator : this.createNode,
            scope : this
        }),
    
        org.microsite.util.BrowserTree.superclass.initComponent.call(this);
    }
});

org.microsite.util.ObjectBrowser = Ext.extend(Ext.Panel, {
    layout : 'border',
   
    treeView : null,
    detailsView : null,
    
    btnRefresh : null,
    btnCreate : null,
    btnDelete : null,
    btnEdit : null,
    
    mCreate : null,
    
    border : false,
    
    root : null,
    
    nodeFilter : function(ctype) {
        return true;
    },
   
    initComponent : function() {
        this.treeView = new org.microsite.util.BrowserTree({
            root : this.root
        });
        
        this.detailsView = new Ext.Panel({
            bodyStyle : 'padding: 5px',
            autoScroll : true,
            region : 'center',
            layout : 'fit'
        });
        
        this.btnRefresh = new Ext.Button({
            iconCls : 'refresh',
            text : 'Refresh',
            tooltip : 'Refresh view',
            handler : this.onRefresh,
            scope : this
        });
        this.mCreate = new Ext.menu.Menu();
        this.btnCreate = new Ext.Button({
            iconCls : 'hostcreate',
            text : 'Create',
            tooltip : 'Create a new entry',
            menu : this.mCreate
        });
        this.btnDelete = new Ext.Button({
            iconCls : 'hostdelete',
            text : 'Delete',
            tooltip : 'Delete host',
            disabled : true,
            handler : this.onDelete,
            scope : this
        });
        this.btnEdit = new Ext.Button({
            iconCls : 'hostedit',
            text : 'Edit',
            tooltip : 'Edit host',
            disabled : true,
            handler : this.onEdit,
            scope : this
        });
        
        Ext.apply(this, {
            items : [{
	                layout : 'fit',
	                items : [this.treeView],
            
		            region : 'west',
                    width : 250,
		            autoScroll : true,
		            containerScroll : true,
		            split : true
                }, this.detailsView],
            tbar : [this.btnRefresh,this.btnCreate,this.btnEdit,this.btnDelete]
        });

        org.microsite.util.ObjectBrowser.superclass.initComponent.apply(this);
        
        this.treeView.getSelectionModel().on('selectionchange', this.onNodeSelected, this);
    },
    
    onNodeSelected : function(tree, node) {
        var n = this.treeView.getSelectionModel().getSelectedNode();
        this.btnEdit.setDisabled(!(n && n.attributes.data.id));
        this.btnDelete.setDisabled(!(n && n.attributes.data.id));
        if (n) {
            var vh = org.microsite.util.ViewRegistry.views[n.attributes.data.getType()];
            var ctypes = vh.getChildTypes(n.attributes.data);
            this.btnCreate.setDisabled(ctypes.length == 0);
            this.mCreate.removeAll();
            for (var i = 0; i < ctypes.length; i++) {
                this.mCreate.add({
                    text : ctypes[i].prototype.getType(),
                    handler : this.onCreateNode,
                    scope : this,
                    disabled : !this.nodeFilter(ctypes[i])
                });
            }
            vh.fillData(n.attributes.data, function(tmp) {
                vh.template.overwrite(this.detailsView.body, tmp);
            }, this);
        }
    },
    
    onRefresh : function(btn, e) {
        var selection = this.treeView.getSelectionModel().getSelectedNode();
        this.treeView.store.reload({
            callback: function() {
                if (selection) {
                    this.treeView.getSelectionModel().select(selection);
                    this.onNodeSelected(this.treeView, selection);
                }
            },
            scope : this
        });
        
    },
    
    onCreateNode : function(mi, e) {
        var n = this.treeView.getSelectionModel().getSelectedNode();
        var vh = org.microsite.util.ViewRegistry.views[mi.initialConfig.text];
        if (vh.editor) {
            var win = new vh.editor({ parentObject : n.attributes.data });
            win.on('change', function(data) {
                if (data) {
                    vh.service.create(data, {
                        callback : function(pdata) {
                            n.appendChild(this.treeView.createNode(n, pdata));
                        },
                        scope : this
                    });
                }
            }, this);
            win.show();
        }
    },
    
    onDelete : function(btn, e) {
        var n = this.treeView.getSelectionModel().getSelectedNode();
        var vh = org.microsite.util.ViewRegistry.views[n.attributes.data.getType()];
        Ext.MessageBox.confirm('Warning', 'Do you really want to delete this ' + n.attributes.data.getType() + '?<br/><b>'
                + n.attributes.data.name + ' (' + host.ip + ')</b>', function(btn) {
            if (btn == 'yes') {
                vh.service.remove(n.attributes.data.id, {
                    callback : function() {
                        this.onRefresh.call(this);
                    },
                    scope : this
                });
            }
        }, this);
    },
    
    onEdit : function(btn, e) {
        var n = this.treeView.getSelectionModel().getSelectedNode();
        var vh = org.microsite.util.ViewRegistry.views[n.attributes.data.getType()];
        if (vh.editor) {
            vh.service.edit(n.attributes.data.id, {
                callback : function(d) {
                    var task = {
                        run : function() {
                            vh.service.keep(d.id);
                        },
                        interval : 180000
                    };
                    Ext.TaskMgr.start(task);
		            var win = new vh.editor({ data : d });
		            win.on('close', function(w) {
                        Ext.TaskMgr.stop(task);
		                if (!win.success) vh.service.release(d.id);
		            }, this);
		            win.on('change', function(data) {
		                if (data) {
		                    vh.service.update(data, {
		                        callback : function() {
		                            var parentNode = n.parentNode;
		                            var node = this.treeView.createNode(parentNode, data);
		                            parentNode.replaceChild(node, n);
		                            node.select();
		                        },
		                        scope : this
		                    });
		                }
		            }, this);
		            win.show();
                },
                scope : this
            });
        }
    }
});

org.microsite.util.ObjectBrowserWindow = Ext.extend(Ext.Window, {
    title : 'Manage hosts',
    closable : true,
    modal : false,
    width : 700,
    height : 400,
    layout : 'fit',
    iconCls : 'hosticon',
    
    browserConfig : {},

    initComponent : function() {
        var browser = new org.microsite.util.ObjectBrowser(this.browserConfig);
        Ext.apply(this, {
            border : false,
            items : [browser]
        });
        org.microsite.util.ObjectBrowserWindow.superclass.initComponent.apply(this);
    }
});
